home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
progjour
/
1991
/
02
/
file.asm
< prev
next >
Wrap
Assembly Source File
|
1990-10-31
|
5KB
|
257 lines
title file i/o for block storage
include asm.inc
public check_block_file
public open_block_file
public read_block_file
public set_block_handle
NULL_HANDLE equ 0
NULL_ID equ 0
file_str struc
f_next dd ?
f_size dd ?
f_index dw ? ; block index
f_id dw ?
file_str ends
f_name equ (size file_str)
.data?
file_list dd ?
file_end dd ?
file_count dw ?
current_id dw ?
current_handle dw ?
.const
ertx_file_id db 'Bad file id',0
ertx_file_missing db 'File missing',0
ertx_too_big db 'File too big',0
.code
extn move_file_pointer,set_strerror,read_from_file,open_input_file,save_most
extn close_file,strcmpi,input_file_size,strlenz,calloc,strcpy
;; change current file
;
; entry DX file id
; exit Cf if file not found
; uses SI,DS
;
change_current_file proc
pushm ax,bx
mov current_id[bp],NULL_ID
movx bx,NULL_HANDLE ; close current file
xchg bx,current_handle[bp]
cmpx bx,NULL_HANDLE
je ccf1 ; if no file open
call close_file
ccf1: lds si,file_list[bp]
jmp ccf3
ccf2: lds si,f_next[si] ; search file structures
ccf3: mov ax,ds
or ax,si
je ccf5 ; if file id not found
cmp dx,f_id[si]
jne ccf2 ; if wrong file, keep searching
lea si,f_name[si] ; open file
call open_input_file
jc ccf5
mov current_handle[bp],bx ; set handle and file id
mov current_id[bp],dx
ccf4: popm bx,ax
ret
ccf5: lea ax,ertx_file_missing ; *File missing*
call set_strerror
jmp ccf4
change_current_file endp
;; check block file
;
; entry DS:SI file name
; exit BX file id or 0 if unknown file
;
check_block_file proc
pushm di,es
les di,file_list[bp]
jmp cbf2
cbf1: les di,es:f_next[di]
cbf2: mov bx,es
or bx,di
stc
jz cbf3 ; if file not found
push di
lea di,f_name[di]
call strcmpi
pop di
jne cbf1 ; if wrong file
mov bx,es:f_id[di]
clc
cbf3: popm es,di
ret
check_block_file endp
;; current file size
;
; exit CX file size in 16k blocks
; Cf if unexpected error
; uses AX
;
current_file_size proc
pushm bx,dx
mov bx,current_handle[bp]
call input_file_size
jc cfs1 ; if unexpected error
mov cx,BLOCK_SIZE ; divide file size by 16k to get
cmp dx,cx ; block count
jae cfs2 ; if too many 16k blocks
div cx
add dx,-1 ; adjust count for partial block
adc ax,ZER0
mov cx,ax
cfs1: popm dx,bx
ret
cfs2: lea ax,ertx_too_big ; *File too big*
call set_strerror
jmp cfs1
current_file_size endp
;; link new file
;
; entry ES:DI file structure
; exit AX file structure count
;
link_new_file proc
inc file_count[bp]
mov ax,file_count[bp]
cmp ax,1
je lnf1 ; if first file structure
pushm si,ds ; else add new file structure to
lds si,file_end[bp] ; the end of the list
mov wptr f_next[si],di
mov wptr f_next[si+2],es
popm ds,si
jmp lnf2
lnf1: mov wptr file_list[bp],di ; set 1st entry in file structure list
mov wptr file_list[bp+2],es
lnf2: mov wptr file_end[bp],di ; set end of file structure list
mov wptr file_end[bp+2],es
ret
link_new_file endp
;; open block file
;
; entry DS:SI file name
; exit CX file size in 16k blocks
; DX file id (1..n)
; Cf if file not found or no storage
; uses AX
;
open_block_file proc
pushm bx,di,si,ds,es
call strlenz ; allocate file structure
add cx,size file_str
call calloc
jc obf1 ; if no memory
call link_new_file ; link file struct to end of file list
mov dx,ax
mov es:f_id[di],ax
lea di,f_name[di] ; copy file name into struct
call strcpy
call change_current_file ; close current file and open new file
jc obf1 ; if file not found
call current_file_size ; get number of 16k blocks in file
obf1: popm es,ds,si,di,bx
ret
open_block_file endp
;; read block file
;
; entry AX file block index (0..n)
; BX file id (1..n)
; ES:DI transfer address
; exit AX byte count
; Cf if error
;
read_block_file proc
call save_most
cmp bx,current_id[bp]
je rbf1 ; if file is already open
mov dx,bx ; else open file (new current file)
call change_current_file
jc rbf2 ; if file missing or other error
rbf1: mov cx,BLOCK_SIZE ; set file position
mul cx
mov bx,current_handle[bp]
call move_file_pointer
jc rbf2 ; if unexpected error
call read_from_file ; read block from file
rbf2: ret
read_block_file endp
;; set block handle
;
; entry BX block handle
; DX file id
; exit Cf if bad file id
; uses AX,CX,SI,DS
;
set_block_handle proc
mov cx,dx
jcxz sbh3 ; if bad file id
lds si,file_list[bp] ; advance through file structure list
jmp sbh2 ; to selected entry
sbh1: lds si,f_next[si]
sbh2: mov ax,ds
or ax,si ; (Cf=0)
jz sbh3 ; if bad file id
loop sbh1
mov f_index[si],bx
ret
sbh3: lea ax,ertx_file_id ; *Bad file id*
jmp set_strerror
set_block_handle endp
end